package model;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.DuplicateKeyException;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import databeans.MailingList;
import databeans.Survey;
import interfas.SurveyInterface;

public class SurveyDAO implements SurveyInterface {

	private BeanFactory<Survey> factory;
	private int sid = 1;
	
	public SurveyDAO() throws DAOException {
		try {
			BeanTable<Survey> table = BeanTable.getInstance(Survey.class,"survey");
			if (!table.exists())
				table.create("sid");
			
			table.setIdleConnectionCleanup(true);
			factory = table.getFactory();
			
			if (factory.getBeanCount() > 0)
				sid = factory.match(MatchArg.max("sid"))[0].getSid() + 1;
			
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public void create(Survey survey, UserDAO userDAO, MailingListDAO mlDAO) throws DAOException {
		try {
			// Check for foreign key constraint
			if (userDAO.lookup(survey.getUserid()) == null) {
				throw new DAOException("userid must exist in User table");
			}
			MailingList[] ml = mlDAO.getMailingListByName(survey.getMailinglist());
			if (!(survey.getMailinglist().equals("")) && (ml == null || ml.length == 0)) {
				throw new DAOException("mailinglist must exist in MailingList table");
			}
			
			Transaction.begin();
			Survey dbSurvey = factory.create(survey.getSid());
			factory.copyInto(survey, dbSurvey);
			sid++;
			Transaction.commit();
		} catch (DuplicateKeyException e) {
			throw new DAOException("A survey with sid " + survey.getSid() + " already exists");
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	public Survey lookup(int sid) throws DAOException {
		try {
			return factory.lookup(sid);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public Survey[] getUserSurveys(String userid) throws DAOException {
		try {
			return factory.match(MatchArg.equals("userid", userid));
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}

	public void updateTitle(Survey survey) throws DAOException {
		try {
			Transaction.begin();
			Survey dbSurvey = lookup(survey.getSid());
			if (dbSurvey == null)
				throw new DAOException("Survey with sid " + survey.getSid() + " doesn't exist");
			dbSurvey.setTitle(survey.getTitle());
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}
	
	public void updateSubmitted(Survey survey) throws DAOException {
		try {
			Transaction.begin();
			Survey dbSurvey = lookup(survey.getSid());
			if (dbSurvey == null)
				throw new DAOException("Survey with sid " + survey.getSid() + " doesn't exist");
			dbSurvey.setSent(survey.getSent());
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}
	
	public void updateMailingList(Survey survey, MailingListDAO mlDAO) throws DAOException {
		try {
			Transaction.begin();
			Survey dbSurvey = lookup(survey.getSid());
			if (dbSurvey == null)
				throw new DAOException("Survey with sid " + survey.getSid() + " doesn't exist");
			MailingList[] ml = mlDAO.getMailingListByName(survey.getMailinglist());
			if (ml == null || ml.length == 0)
				throw new DAOException("mailinglist must exist in MailingList table");
			dbSurvey.setMailinglist(survey.getMailinglist());
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}
	
	public void delete(int sid) throws DAOException {
		try {
			Transaction.begin();
			Survey dbSurvey = lookup(sid);
			if (dbSurvey == null)
				throw new DAOException("Survey with sid " + sid + " doesn't exist");
			factory.delete(sid);
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}
	
	public int size() throws DAOException {
		try {
			return factory.getBeanCount();
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public int getSid() {
		return sid;
	}
}
